package com.museum.security;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.museum.common.exception.CaptchaException;
import com.museum.common.lang.Const;
import com.museum.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * 将CaptchaFilter不作为Bean注入,在Security配置中使用new的方式让Security来管理他，
 * 这是因为我们将Filter作为Bean注入后，Spring会自动将其管理，即使你在Security中配置了忽略，Spring还是照样会将请求使用过滤器进行过滤
 * 图片验证码校验过滤器，在登录过滤器前
 * @author Akihi
 */
@Slf4j
@RequiredArgsConstructor
public class CaptchaFilter extends OncePerRequestFilter {

    private final RedisUtil redisUtil;

    private final LoginFailureHandler loginFailureHandler;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        //获取uri
        String url = request.getRequestURI();
        // 1. 如果是post方式 的登录请求，则校验输入的验证码是否正确
        if ("/login".equals(url) && "POST".equalsIgnoreCase(request.getMethod())) {
            try{
                log.debug("获取到login链接，正在校验验证码 -- " + url);
                // 校验验证码
                validate(request);
            } catch (CaptchaException e) {
                // 交给认证失败处理器
                loginFailureHandler.onAuthenticationFailure(request, response, e);
                // 一定要记得结束
                return;
            }
        }
        filterChain.doFilter(request, response);
    }

    // 校验验证码逻辑
    private void validate(HttpServletRequest request) throws CaptchaException {
        //获取请求中的token和code
        String code = request.getParameter("code");
        String key = request.getParameter("token");
        log.info("code--->{}, token--->{}",code, key);
        if (StringUtils.isBlank(code) || StringUtils.isBlank(key)) {
            throw new CaptchaException("验证码不能为空");
        }
        if (!code.equals(redisUtil.hget(Const.CAPTCHA_KEY, key))) {
            throw new CaptchaException("验证码错误");
        }
        // 一次性使用
        redisUtil.hdel(Const.CAPTCHA_KEY, key);
    }
}
